package com.tdcy.framework.mail;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.URLDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import com.tdcy.framework.mail.entity.MailAttachFile;
import com.tdcy.framework.mail.entity.MailAttachLocalFile;
import com.tdcy.framework.mail.entity.MailAttachURL;
import com.tdcy.framework.mail.entity.MailSenderInfo;
import com.tdcy.framework.mail.exception.HHMailException;

/**
 * 简单邮件（不带附件的邮件）发送器
 */
public class SimpleMailSender {
	public static final String DEFAULT_CONFIG_PATH = "mail.properties";

	public static final String DEFAULT_CONTENT_TYPE = "text/html; charset=utf-8";

	public static final String DEFAULt_SMTPTYPE = "smtp";

	private boolean debug = false;

	private String contentType;// 内容类型

	private String smtpType;// 邮件类型

	private boolean useproperties = false; // 是否使用配置文件

	public boolean isDebug() {
		return debug;
	}

	public void setDebug(boolean debug) {
		this.debug = debug;
	}

	public String getContentType() {
		return contentType;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getSmtpType() {
		return smtpType;
	}

	public void setSmtpType(String smtpType) {
		this.smtpType = smtpType;
	}

	public boolean isUseproperties() {
		return useproperties;
	}

	public void setUseproperties(boolean useproperties) {
		this.useproperties = useproperties;
	}

	public SimpleMailSender() {

	}

	public SimpleMailSender(boolean useproperties) {
		this.useproperties = useproperties;
	}

	public SimpleMailSender(boolean useproperties, boolean debug) {
		this.useproperties = useproperties;
		this.debug = debug;
	}

	/**
	 * 以HTML格式发送邮件
	 * 
	 * @param mailInfo
	 *            待发送的邮件的信息
	 */
	public void sendMail(MailSenderInfo mailInfo) {
		if (smtpType == null) {
			smtpType = DEFAULt_SMTPTYPE;
		}

		if (contentType == null) {
			contentType = DEFAULT_CONTENT_TYPE;
		}

		try {
			Properties props = getMailProperties(mailInfo);
			Session session = Session.getDefaultInstance(props, null);
			if (debug) {
				session.setDebug(debug);
			}

			Transport transport = session.getTransport(smtpType);
			transport.connect(mailInfo.getMailServerHost(), mailInfo.getUserName(), mailInfo.getPassword());
			MimeMessage msg = new MimeMessage(session);

			// 设置邮件信息
			this.setMailInfo(msg, mailInfo);

			transport.sendMessage(msg, msg.getAllRecipients());
			System.out.println("邮件发送！");
			transport.close();
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new HHMailException(ex);
		}
	}

	/**
	 * 设置邮件属性
	 * 
	 * @param msg
	 * @param mailInfo
	 * @throws AddressException
	 * @throws MessagingException
	 * @throws UnsupportedEncodingException
	 * @throws MalformedURLException
	 */
	private void setMailInfo(MimeMessage msg, MailSenderInfo mailInfo) throws AddressException, MessagingException, UnsupportedEncodingException, MalformedURLException {
		// 设置邮件信息
		msg.setSentDate(new Date());
		msg.setFrom(new InternetAddress(mailInfo.getFromAddress()));

		List<String> adds = mailInfo.getToAddress();
		InternetAddress[] toAddress = new InternetAddress[adds.size()];
		if (adds != null && adds.size() > 0) {
			for (int i = 0; i < adds.size(); i++) {
				toAddress[i] = new InternetAddress(adds.get(i));
			}
		}

		msg.setRecipients(Message.RecipientType.TO, toAddress); // 发送对象为多人

		msg.setSubject(mailInfo.getSubject());

		// MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象
		Multipart mainPart = new MimeMultipart();
		// 创建一个包含HTML内容的MimeBodyPart
		BodyPart html = new MimeBodyPart();
		// 设置HTML内容
		html.setContent(mailInfo.getContent(), contentType);
		mainPart.addBodyPart(html);
		// 将MiniMultipart对象设置为邮件内容
		msg.setContent(mainPart);
		// 加载附件
		this.setAttacheFile(mainPart, mailInfo);

		msg.saveChanges();
	}

	/**
	 * 加入附件
	 * 
	 * @param mainPart
	 * @param mailInfo
	 * @throws MessagingException
	 * @throws MalformedURLException
	 * @throws UnsupportedEncodingException
	 */
	private void setAttacheFile(Multipart mainPart, MailSenderInfo mailInfo) throws MessagingException, MalformedURLException, UnsupportedEncodingException {
		List<MailAttachFile> fileNames = mailInfo.getAttachFileNames();
		if (fileNames != null && fileNames.size() >= 0) {
			for (int i = 0; i < fileNames.size(); i++) {
				MailAttachFile file = fileNames.get(i);
				BodyPart messageBodyPart = new MimeBodyPart();

				DataSource source = null;
				if (file instanceof MailAttachLocalFile) {
					source = new FileDataSource(((MailAttachLocalFile) file).getFilePath());
				} else if (file instanceof MailAttachURL) {
					MailAttachURL urlFile = (MailAttachURL) file;
					if (urlFile.getUrl() != null) {
						source = new URLDataSource(urlFile.getUrl());
					} else if (urlFile.getUrlPath() != null) {
						URL url = new URL(urlFile.getUrlPath());
						source = new URLDataSource(url);
					}
				}

				// 添加附件的内容
				messageBodyPart.setDataHandler(new DataHandler(source));
				// 添加附件的标题
				messageBodyPart.setFileName(MimeUtility.encodeText(file.getName()));
				mainPart.addBodyPart(messageBodyPart);
			}
		}
	}

	/**
	 * 获取邮件属性
	 * 
	 * @param mailInfo
	 * @return
	 */
	private Properties getMailProperties(MailSenderInfo mailInfo) {
		Properties props = new Properties();

		Properties config = new Properties();
		if (useproperties) {
			config = PropertiesHelper.loadProperties(DEFAULT_CONFIG_PATH);
		}

		if (mailInfo.getMailServerHost() == null || mailInfo.getMailServerHost().trim().equals("")) {
			props.put("mail." + smtpType + ".host", config.get("mail.host"));
			props.put("mail." + smtpType + ".port", config.get("mail.port"));

			String userName = mailInfo.getUserName();
			if ((userName != null) && (userName.length() > 0)) {
				props.put("mail." + smtpType + ".auth", config.get("mail.validate"));
			}
		} else {
			props.put("mail." + smtpType + ".host", mailInfo.getMailServerHost());
			props.put("mail." + smtpType + ".port", mailInfo.getMailServerPort());

			String userName = mailInfo.getUserName();
			if ((userName != null) && (userName.length() > 0)) {
				props.put("mail." + smtpType + ".auth", mailInfo.isValidate());
			}
		}

		return props;
	}

}
